export {}
interface Fish {
	name1: string
}
interface Water {
	name2: string
}
interface Bird {
	name3: string
}
interface Sky {
	name4: string
}
type Condition<T> = T extends Fish?Water:Sky
let con:Condition<Fish> = {name2:'水'}

//条件类型分发
let con1:Condition<Fish|Bird> = {
	name2:''
}
let con2:Condition<Fish|Bird> = {
	name4:''
}

type Condition2<T> = {t:T} extends {t:Fish}? Water : Sky

//条件类型分发
let con3:Condition<Fish|Bird> = {
	name2:''
}
let con4:Condition<Fish|Bird> = {
	name4:''
}

//找出T类型中U不包含的部分
type Diff<T,U>= T extends U?never:T;
type R = Diff<'a'|'b'|'c'|'d', 'a'|'b'|'c'>
type Filter<T, U> = T extends U ? T : never;
type R1 = Filter<string | number | boolean, number>;

//内置条件类型
//Exclude
type Exclude<T,U> = T extends U ? never : T;
type R4 = Exclude<'a' | 'b' | 'c' | 'd','a'|'b'>

//Extract
type R5 = Extract<'a' | 'b' | 'c' | 'd','a'|'b'>

// NonNullable
type NonNullable<T> = T extends null |undefined? never:T;
type R6 = NonNullable<'a'|null| undefined>

//ReturnType  infer

type ReturnType<T> = T extends (...args:any[]) => infer R?R:T;

function getUser(){
	return {name:'jin',age:10}
}
type GetUserType = typeof getUser
type ReturnUser = ReturnType<GetUserType>

let u : ReturnUser = {
	name:"June",
	age:10
}

type Parameters<T> =T extends ((...args:infer P) => any) ? P :never
type X1 = {}
type ParamsType =Parameters<X1>


class Person8 {
	name: string;
	constructor(name:string){
		this.name = name
	}
	getName(){console.log(this.name)}
}

type Params = ConstructorParameters<typeof Person8>

type Person8Intance = InstanceType<typeof Person8>

let instance:Person8Intance = {
	name:'jack',
	getName(){}
}

// infer 应用案例
// tuple 转union
type ElementOf<T> = T extends Array<infer E>?E:never;
type Ttuple = [string,number,boolean];
type TupleToUnion = ElementOf<Ttuple>;


type First <T> = T extends {name:infer A}? A:never;
type F1 = First<{name:string}>
//联合类型转交叉类型
//string | number => string & number
type T1 = {name:string}
type T2 = {age:number}
type ToIntersection<T> = T extends {}?U:never;
type T3 = ToIntersection<{a:(x:T1)=>void, b:(x:T2)=> void}>
let t33:T3 = {name:'',age:10}